<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
    <title>选中文字弹出对话框</title>
    <style type="text/css">
      * {
        margin: 0px;
        padding: 0px;
      }
      .box {
        width: 500px;
        height: 200px;
        border: 1px solid #ccc;
        position: relative;
        left: 0px;
        top: 0px;
        margin: 100px auto;
      }
      .box .box1 {
        width: 500px;
        height: 200px;
        font: 15px/20px "微软雅黑";
        text-indent: 2em;
        position: absolute;
        left: 0px;
        top: 0px;
      }
      .box .box2 {
        width: 120px;
        height: 25px;
        text-align: center;
        position: absolute;
        left: 0px;
        top: 0px;
        background-color: yellow;
        display: none;
      }
      .box .box2 span {
        width: 25px;
        height: 25px;
        font: 15px/20px "微软雅黑";
        color: blue;
      }
    </style>
    <script type="text/javascript">
      function $(id) {
        return document.getElementById(id);
      }
      window.onload = function () {
        $("xuan").onmouseup = function (event) {
          //鼠标点击松开之后，就会触发onmouseup事件;
          // var evt=event||window.event;
          // var pointerx=evt.clientX-$("xuan").offsetLeft;//鼠标在盒子内部的横坐标;
          // var pointery=evt.clientY-$("xuan").offsetTop;//鼠标在盒子内部的纵坐标;
          var evt = event || window.event;
          x = evt.clientX - $("xuan").offsetLeft - 380;
          y = evt.clientY - $("xuan").offsetTop - 100;
          var txt = window.getSelection();
          //限制弹出对话框的显示区域;
          if (x < 0) {
            x = 0;
          } else if (x > 380) {
            x = 380;
          }
          if (y < 0) {
            y = 0;
          } else if (y > 175) {
            y = 175;
          }
          //获取用户选中的文本;
          var txt = window.getSelection
            ? window.getSelection().toString()
            : document.selection.createRange().text;

          var range = window.getSelection().getRangeAt(0);
          var rectList = range.getClientRects();
          console.log(rectList);
          let dom = document.createDocumentFragment();
          function contains(rect1, rect2) {
            return (
              (rect2.right <= rect1.right) &&
              (rect2.left >= rect1.left) &&
              (rect2.top >= rect1.top) &&
              (rect2.bottom <= rect1.bottom)
            );
          }
          rectList = [...rectList]
          rectList = rectList.filter((box) => {
            for (var i = 0; i < rectList.length; i++) {
              if (rectList[i] === box) {
                return true;
              }
              let contained = contains(rectList[i], box);
              if (contained) {
                return false;
              }
            }
            return true;
          })

          rectList.forEach(val => {
            let div = document.createElement("div");
            div.style.position = 'absolute'
            div.style.zIndex = -1;
            div.style.height = val.height + 'px';
            div.style.width = val.width + 'px';
            div.style.left = val.left + 'px';
            div.style.top = val.top + 'px';
            div.style.background = 'red';
            dom.appendChild(div);
          })
          rectList = [rectList[0]]
          rectList.forEach(val => {
            let div = document.createElement("div");
            div.innerText = "😊"
            div.style.position = 'absolute'
            div.style.zIndex = 1;
            // div.style.height = val.height + 'px';
            // div.style.width = val.width + 'px';
            div.style.left = val.left + val.width + 'px';
            div.style.top = val.top - val.height / 2 + 'px';
            // div.style.background = 'red';
            // div.style.borderBottom = '1px solid red';
            dom.appendChild(div);
          })
          document.body.appendChild(dom)
          if (txt) {
            $("yt").style.left = x + "px";
            $("yt").style.top = y + "px";
            $("yt").style.display = "block";
          }
        };
        //鼠标点击一次就会消失弹出的对话框;
        document.onmousedown = function (event) {
          var evt = event || window.event;
          if (evt.target.id != "yt") {
            $("yt").style.display = "none";
          }
          window.getSelection().removeAllRanges();
        };
        document.οnclick = function (event) {
          //取消选中的文本;
          window.getSelection().removeAllRanges();
          window.getSelection?window.getSelection().removeAllRanges():
          document.selection.empty();
          $("yt").style.display = "none";
        };
      };
    </script>
  </head>
  <body>
    <div class="box">
      <div class="box1" id="xuan">
        打算开发商卡大家都打算开发商卡大家都打算开发商卡大家都
        <p>打算开发商卡大家都打算开发商卡大家都打算开发商卡大家都打算</p>
        开发商卡大家都打算开发商卡大家都打算开发商卡大家都打算开发商卡大家都打算开
        发商卡大家都打算开发商卡大家都打算开发商卡大家都打算开发商卡大家都打算开发商卡大
        <p>家都打算开发商卡大家都打<span>算开发商卡大家都打算开发商</span>卡大家都打算开发商卡大家都打算开发</p>
        商卡大家都打算开发商卡大家都打算开发商卡大家都打算开发商卡大家都打算开发商卡大家都
        打算开发商卡大家都打算开发商卡大家都打算开发商卡大家都打算开发商卡大家都
      </div>
      <div class="box2" id="yt">
        <span>复制</span>
        <span>剪切</span>
        <span>全选</span>
      </div>
    </div>
  </body>
</html>
